home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / xref.zip / XRF.C < prev    next >
Text File  |  1986-05-24  |  7KB  |  358 lines

  1. /*              XRF.C - 'C' and 'PASCAL' cross reference program.
  2.                 from 6/86 Computer Language Magazine
  3.                      
  4.         Language: Microsoft C
  5.         Note:
  6.                 Uses recursive functions, so when linking, you must include
  7.                 the LINK switch '/SWITCH:48000'.
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <ctype.h>
  13. #include <string.h>
  14. #include <io.h>
  15. #include <malloc.h>
  16.  
  17. #ifndef TRUE
  18.     #define TRUE 1
  19.     #define FALSE 0
  20. #endif
  21.  
  22. #define MAX_DEF   500        /* maximum language definitions */
  23. #define NAME_CHARS  "._"   /* punctuation allowed in Names */
  24. #define DQUOTE     0x22    /* ASCII Double Quote Character */
  25. #define SQUOTE     0x27    /* ASCII Single Quote Character */
  26. FILE *fopen(), *infile, *outfile;
  27. char   lbuff[120];            /* current line holder */
  28. int    lcnt     = 1;            /* line counter */
  29. int    lptr     = 0;            /* assume empty line buffer */
  30. int     is_c     = FALSE;     /* is input source in "C"? Allow { } */
  31. struct numrec
  32. {
  33.     int number;                    /* line number of symbol occurance */
  34.     struct numrec *nnext;    /* next number of symbol line */
  35. };
  36. struct symrec
  37. {
  38.     char *symbol;                /* symbol string */
  39.     int  count;                    /* symbol occurance counters */
  40.     struct numrec *lnum;        /* line number records */
  41.     struct symrec *lnode;    /* left branch of binary tree */
  42.     struct symrec *rnode;   /* right branch of binary tree */
  43. };
  44. struct symrec *symtab = NULL;    /* declare main symbol table */
  45. char *Exceptions[ MAX_DEF ];    /* language definition table structure */
  46. main(argc, argv)
  47. char *argv[];
  48. int argc;
  49. {
  50.     int c;
  51.     if( (argc < 2) || (argc > 3) )
  52.     {
  53.         printf("XRF: Usage is XRF [input name] <output name>\n");
  54.         exit();
  55.     }
  56.     if(NULL==(infile = fopen(argv[1],"r")) )
  57.     {
  58.         printf("ERROR: Cannot open input file - %s\n",argv[1]);
  59.         exit();
  60.     }
  61.     if( argc == 3 )
  62.     {
  63.         if(NULL==(outfile = fopen( argv[2],"w")) )
  64.         {
  65.             printf("ERROR: Cannot open output file - %s\n",argv[2]);
  66.             exit();
  67.         }
  68.         printf("Generating Listing File - %s\n",argv[2]);
  69.     }
  70.     else
  71.     {
  72.         outfile = stdout;
  73.     }
  74.     load_tbl(argv[1]);
  75.     printf("Language Table Loaded\n");
  76.     /*   Main input and parse loop     */
  77.     while( (c=getc(infile)) != EOF ) filter (c);
  78.     fprintf( outfile, "Symbol Table for File - %s\n",strupr(argv[1]) );
  79.     symprint( symtab );
  80.     printf("\nEnd.\n");
  81. }
  82. /*
  83.         comment processor, quoted text, and punctuation
  84. */
  85. filter( c )
  86. char c;
  87. {
  88.     char cl;
  89.     static is_com = FALSE;
  90.     if( c==DQUOTE)
  91.     {
  92.         while( (c=getc(infile)) != DQUOTE ) if( c==EOF ) return;
  93.         next_char( ' ' );
  94.     }
  95.     else
  96.         if( c==SQUOTE )
  97.         {
  98.             while((c=getc(infile)) != SQUOTE) if(c==EOF) return;
  99.             next_char(' ');
  100.         }
  101.         else
  102.             if((c=='{') && !is_c)
  103.             {
  104.                 while((c=getc(infile)) != '}' ) if(c==EOF) return;
  105.                 next_char( ' ' );
  106.             }
  107.             else
  108.                 if(c == '(')
  109.                 {
  110.                     cl = getc(infile);
  111.                     if (cl==EOF) return;
  112.                     if(cl != '*')
  113.                     {
  114.                         next_char( ' ' );
  115.                         ungetc(cl, infile);
  116.                     }
  117.                     else
  118.                     {
  119.                         is_com = TRUE;
  120.                         while(is_com)
  121.                         {
  122.                             while((c=getc(infile)) != '*' ) if(c==EOF) return;
  123.                             cl = getc(infile);
  124.                             if (cl==EOF) return;
  125.                             if(cl==')') is_com=FALSE;
  126.                             else
  127.                                 ungetc(cl, infile);
  128.                         }
  129.                         next_char(' ');
  130.                     }
  131.                 }
  132.                 else
  133.                     if(c=='/')
  134.                     {
  135.                         cl=getc(infile);
  136.                         if (cl==EOF) return;
  137.                         if(cl != '*')
  138.                         {
  139.                             next_char(' ');
  140.                             ungetc(cl, infile);
  141.                         }
  142.                         else
  143.                         {
  144.                             is_com = TRUE;
  145.                             while(is_com)
  146.                             {
  147.                                 while((c=getc(infile)) != '*') if(c=EOF) return;
  148.                                 cl = getc(infile);
  149.                                 if (cl==EOF) return;
  150.                                 if(cl=='/') is_com = FALSE;
  151.                                 else
  152.                                     ungetc(cl, infile);
  153.                             }
  154.                             next_char(' ');
  155.                         }
  156.                     }
  157.                     else
  158.                     {
  159.                         if(isalnum(c) || strchr(NAME_CHARS, c) || isspace(c) )
  160.                             next_char(c);
  161.                         else
  162.                             if(c=='-')
  163.                             {
  164.                                 if('>' == (c=getc(infile)) )
  165.                                 {
  166.                                     next_char('-');
  167.                                     next_char('>');
  168.                                 }
  169.                                 else
  170.                                 {
  171.                                     ungetc(c, infile);
  172.                                     next_char(' ');
  173.                                 }
  174.                             }
  175.                             else
  176.                                 next_char(' ');
  177.                     }
  178. }
  179.  
  180. /*            symbol process (after comments and quotes have been stripped) */
  181. next_char(a)
  182. char a;
  183. {
  184.     if(isspace(a))
  185.     {
  186.         if(lptr==0)
  187.         {
  188.             if(a == '\n') ++lcnt;
  189.             return;
  190.         }
  191.         lbuff[lptr] = '\0';
  192.         lptr = 0;
  193.         next_sym( lbuff, lcnt);
  194.         if(a=='\n') ++lcnt;
  195.     }
  196.     else
  197.         lbuff[lptr++] = a;
  198. }
  199.  
  200. next_sym(s, n)
  201. char *s;
  202. int n;
  203. {
  204.     struct symrec *newsym();
  205.     
  206.     if (isdigit(s[0])) return;
  207.     
  208.     if (is_lang(s)) return;
  209.     
  210.     symtab = newsym(symtab, s, n);
  211. }
  212.  
  213. struct symrec *newsym(q, w, n)
  214. struct symrec *q;
  215. char *w;
  216. int n;
  217. {
  218.     struct symrec *salloc();
  219.     struct numrec *newnum();
  220.     char *strsave();
  221.     int cond;
  222.     if(q==NULL)
  223.     {
  224.         q = salloc();
  225.         strupr(w);
  226.         q->symbol = strsave(w);
  227.         q->count = 1;
  228.         q->lnum = q->lnode = q->rnode = NULL;
  229.         q->lnum = newnum(q->lnum, lcnt);
  230.     }
  231.     else
  232.         if((cond = strcmp(w, q->symbol)) == 0)
  233.         {
  234.             q->count++;
  235.             q->lnum = newnum( q->lnum, n);
  236.         }
  237.         else
  238.             if(cond<0)
  239.                 q->lnode = newsym( q->lnode, w, n);
  240.             else
  241.                 q->rnode = newsym( q->rnode, w, n);
  242.     return(q);
  243. }
  244.  
  245. struct numrec *newnum(p, n)
  246. struct numrec *p;
  247. int n;
  248. {
  249.     struct numrec *nalloc();
  250.     if(p==NULL)
  251.     {
  252.         p = nalloc();
  253.         p->number = n;
  254.         p->nnext = NULL;
  255.     }
  256.     else
  257.     {
  258.         p->nnext = newnum(p->nnext, n);
  259.     }
  260.     return(p);
  261. }
  262.  
  263. struct symrec *salloc()
  264. {
  265.     return((struct symrec *) malloc(sizeof(struct symrec)));
  266. }
  267.  
  268. struct numrec *nalloc()
  269. {
  270.     return((struct numrec *) malloc(sizeof(struct numrec)));
  271. }
  272.  
  273. char *strsave(str)
  274. char *str;
  275. {
  276.     char *p;
  277.     if((p=malloc(strlen(str)+1)) != NULL) strcpy(p, str);
  278.     if(p==NULL) printf("ERROR: Out of string space.\n");
  279.     return(p);
  280. }
  281.  
  282. symprint(p)
  283. struct symrec *p;
  284. {
  285.     if(p!=NULL)
  286.     {
  287.         symprint(p->lnode);
  288.         fprintf(outfile, "%-15s (%d)\t:\n",p->symbol, p->count);
  289.         numprint(p->lnum, 0);
  290.         symprint(p->rnode);
  291.     }
  292. }
  293.  
  294. numprint(p, i)
  295. struct numrec *p;
  296. {
  297.     if(p != NULL)
  298.     {
  299.         fprintf(outfile, "  %4d", p->number);
  300.         if(!((i+1)%10)) putc('\n', outfile);
  301.         numprint(p->nnext, ++i);
  302.     }
  303.     else
  304.         putc('\n', outfile);
  305. }
  306.  
  307. is_lang(str)
  308. char *str;
  309. {
  310.     int i, j;
  311.     i = 0;
  312.     while(Exceptions[i] != NULL)
  313.     {
  314.         if((j=strcmp(strupr(str), Exceptions[i++])) == 0) return(1);
  315.         else
  316.             if(j<0) return(0);
  317.     }
  318.     return(0);
  319. }
  320.  
  321. load_tbl(iname)
  322. char *iname;
  323. {
  324.     char *cptr;
  325.     char fname[65], symbol[500];
  326.     FILE *tfile;
  327.     int i = 0;
  328.     if(NULL == (cptr=strchr(iname, '.')))
  329.     {
  330.         printf("ERROR: No extension on input file name: %s\n",iname);
  331.         exit();
  332.     }
  333.     sscanf(++cptr, "%s", fname);
  334.     strcat(fname, ".XRF");
  335.     strupr(fname);
  336.     if(0 == strncmp(fname, "C.XRF", 5)) is_c = TRUE;
  337.     if(NULL == (tfile = fopen(fname,"r")))
  338.     {
  339.         printf("ERROR: Cannot open Language Table file: %s\n",fname);
  340.         exit();
  341.     }
  342.     while(i < MAX_DEF)
  343.     {
  344.         if(EOF == fscanf(tfile, "%s", symbol))
  345.         {
  346.             fclose(tfile);
  347.             return;
  348.         }
  349.         else
  350.             Exceptions[i++] = strsave(strupr(symbol));
  351.     }
  352.     printf("ERROR: Language Definition File is too long (Max = %d).\n",MAX_DEF);
  353.     exit();
  354. }
  355.  
  356. _nullcheck()
  357. { }
  358.